package com.fjwt.gz.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.DesensitizedUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fjwt.gz.components.mq.constant.WebSocketConstants;
import com.fjwt.gz.components.mq.websocket.server.PCWsChannelServer;
import com.fjwt.gz.components.oss.model.MockMultipartFile;
import com.fjwt.gz.components.oss.model.OssFileConfig;
import com.fjwt.gz.components.oss.service.OssFileService;
import com.fjwt.gz.core.constants.ApiCodeEnum;
import com.fjwt.gz.core.constants.Constants;
import com.fjwt.gz.core.exception.BizException;
import com.fjwt.gz.core.model.security.GzUserDetails;
import com.fjwt.gz.db.dto.MchInfoDTO;
import com.fjwt.gz.db.entity.AgentInfoEntity;
import com.fjwt.gz.db.entity.MchChannelEntity;
import com.fjwt.gz.db.entity.MchInfoEntity;
import com.fjwt.gz.db.entity.OssRecordEntity;
import com.fjwt.gz.db.dto.PointDTO;
import com.fjwt.gz.db.vo.MchInfoVO;
import com.fjwt.gz.db.vo.NearMchListVo;
import com.fjwt.gz.service.mapper.MchInfoMapper;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 商户信息表 服务实现类
 * </p>
 *
 * @author shiyonghao
 * @since 2025-04-09
 */
@Slf4j
@Service
public class MchInfoService extends ServiceImpl<MchInfoMapper, MchInfoEntity> {

    @Autowired
    private MchChannelService mchChannelService;
    @Autowired
    private OssRecordService ossRecordService;

    @Autowired
    private MchInfoMapper mchInfoMapper;

    @Autowired
    private AgentInfoService agentInfoService;

    @Autowired
    private OssFileService ossFileService;

    @Autowired
    private PCWsChannelServer wsChannelServer;

    public IPage<MchInfoVO> getMchList(IPage iPage, MchInfoDTO mchInfoDTO) {
        if (ObjectUtils.isNotEmpty(mchInfoDTO.getAgentNo())) {
            mchInfoDTO.setAgentNos(agentInfoService.queryAllSubAgentNo(mchInfoDTO.getAgentNo()));
            mchInfoDTO.setAgentNo(null);
        }
        IPage<MchInfoVO> page = mchInfoMapper.getMchList(iPage, mchInfoDTO);

        List<MchInfoVO> records = page.getRecords();

        // 获取机构编号
        Set<String> agentNos = new HashSet<>();
        for (MchInfoVO vo : records) {
            agentNos.add(vo.getAgentNo());
            agentNos.add(vo.getAgentNo1());
            agentNos.add(vo.getAgentNo2());
            agentNos.add(vo.getAgentNo3());
            agentNos.add(vo.getAgentNo4());
        }
        //查询机构信息并转map
        Map<String, AgentInfoEntity> agentInfoMap = new HashMap<>();
        if (!agentNos.isEmpty()) {
            List<AgentInfoEntity> agentInfoList = agentInfoService.getAgentInfos(new ArrayList<>(agentNos));
            agentInfoMap = agentInfoList.stream().collect(Collectors.toMap(AgentInfoEntity::getAgentNo, Function.identity()));
        }

        for (MchInfoVO vo : records) {
            String agentNo = vo.getAgentNo();
            if (StrUtil.isNotEmpty(agentNo)) {
                AgentInfoEntity agentInfo = agentInfoMap.get(agentNo);
                if (agentInfo == null) continue;
                AgentInfoEntity info4 = agentInfoMap.get(vo.getAgentNo4());
                if (null != info4 && 4 == info4.getLevel()) {
                    vo.setOrgName(info4.getAgentName());
                    vo.setOrgCode(info4.getAgentNo());
                }
                //区县
                AgentInfoEntity areaInfo = agentInfoMap.get(vo.getAgentNo3());
                if (null != areaInfo && 3 == areaInfo.getLevel()) {
                    vo.setAreaNameNew(areaInfo.getAgentName());
                    vo.setArea(areaInfo.getAgentNo());
                }
                //地市
                AgentInfoEntity info2 = agentInfoMap.get(vo.getAgentNo2());
                if (null != info2 && 2 == info2.getLevel()) {
                    vo.setCityName(info2.getAgentShortName());
                    vo.setCity(info2.getAgentNo());
                }
                //查客户经理
//                entity.setGhName(entity.getCreatedBy());
            }
            // 数据脱敏
            vo.setPhone(DesensitizedUtil.mobilePhone(vo.getPhone()));
//            page.setRecords(records);
        }
        return page;
    }

    /**
     * 根据商户号查询商户信息
     */
    public MchInfoVO getMchInfo(String mchNo) {
        List<MchInfoVO> mchInfoList = mchInfoMapper.getMchInfo(mchNo);
        if (ObjectUtils.isEmpty(mchInfoList)) {
            throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_SELETE);
        }
        MchInfoVO mchInfo = mchInfoList.get(0);

        // 查询商户归属机构信息
        List<String> agentNos = Stream.of(mchInfo.getAgentNo1(), mchInfo.getAgentNo2(), mchInfo.getAgentNo3(), mchInfo.getAgentNo4())
                .filter(Objects::nonNull).toList();
        if (ObjectUtils.isNotEmpty(agentNos)) {
            mchInfo.addExt("parentAgentNo", agentNos);
            List<AgentInfoEntity> agentInfos = agentInfoService.getAgentInfos(agentNos);
            if (ObjectUtils.isNotEmpty(agentInfos)) {
                List<String> agentNames = agentInfos.stream().map(AgentInfoEntity::getAgentName).toList();
                mchInfo.addExt("parentAgentName", agentNames);
            }
        }
        // 查询商户进件信息
        List<MchChannelEntity> mchChannelEntityList = mchChannelService.list(MchChannelEntity.gw()
                .eq(MchChannelEntity::getMchNo, mchInfo.getMchNo()));
        mchInfo.setMchChannelEntityList(mchChannelEntityList);
        return mchInfo;
    }

    /**
     * 导入平台商户数据
     * 时永浩
     * 2024-05-27
     * @param ossFileUrl oss文件地址
     * return  已存在的商户号集合
     */
    @Transactional(rollbackFor = Exception.class)
    public String importMchInfo(String ossFileUrl, String bizType,String currentAgentNo) {
        if (ossFileUrl.isEmpty()) {
            throw new BizException("参数有误，请检查");
        }
        JSONObject  result= getMchInfoToList(ossFileUrl, bizType,  currentAgentNo);
        List<JSONObject> failList = (List<JSONObject>) result.get("fail");
        List<MchInfoVO> successList = (List<MchInfoVO>) result.get("success");
        log.info("导入平台商户文件解析数据：{}", JSONUtil.toJsonStr(successList));
        if (ObjectUtils.isEmpty(successList) &&  ObjectUtils.isEmpty(failList)){
//            wsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()),0, "导入平台商户数据", "商户数据为空！", WebSocketConstants.ImportStatus.FAIL);
            return "";
        }
        if (ObjectUtils.isEmpty(successList) &&  ObjectUtils.isNotEmpty(failList)) {
            return importMchFailUrl(failList);
        }

        Date date = new Date();

        Map<String, List<MchInfoVO>> mchInfoMap = successList.stream().collect(Collectors.groupingBy(MchInfoVO::getMchNo));

        List<MchInfoEntity> newMchInfoList = new ArrayList<>();
        List<MchChannelEntity> newMchChannelList = new ArrayList<>();
        for (Map.Entry<String, List<MchInfoVO>> mchInfo : mchInfoMap.entrySet()) {
            MchInfoEntity createMchInfo = new MchInfoEntity();
            BeanUtils.copyProperties(mchInfo.getValue().get(0), createMchInfo);
            createMchInfo.setCreatedUid(GzUserDetails.getCurrentUserDetails().getSysUserId());
            createMchInfo.setCreatedAt(date);
            createMchInfo.setUpdatedAt(date);
            newMchInfoList.add(createMchInfo);

            for (MchInfoVO info : mchInfo.getValue()) {
                //如果ifCode不为空，则添加商户渠道表数据
               if (StringUtils.isNotEmpty(info.getIfCode())) {
                   MchChannelEntity createMchChannelEntity = new MchChannelEntity();

                   BeanUtils.copyProperties(info, createMchChannelEntity);
                   createMchChannelEntity.setState(info.getChannelState());
                   createMchChannelEntity.setCreatedAt(date);
                   createMchChannelEntity.setUpdatedAt(date);
                   newMchChannelList.add(createMchChannelEntity);
               }
            }
        }
        if (ObjectUtils.isNotEmpty(newMchInfoList)){
            mchInfoMapper.batchInsert(newMchInfoList);
        }
        if (ObjectUtils.isNotEmpty(newMchChannelList)){
            mchChannelService.saveBatch(newMchChannelList);
        }
        if (ObjectUtils.isNotEmpty(failList)) {
            return importMchFailUrl(failList);
        }
        return "";
    }

    private static void toJsonSet(MchInfoVO item, List<JSONObject> failList,String failRemark) {
        JSONObject failObject = new JSONObject();
        failObject.put("mchNo", item.getMchNo());
        failObject.put("mchName", item.getMchName());
        failObject.put("mchShortName", item.getMchShortName());
        failObject.put("agentNo", item.getAgentNo());
        failObject.put("longitude", item.getLongitude());
        failObject.put("latitude", item.getLatitude());
        failObject.put("address", item.getAddress());
        failObject.put("agentNo1", item.getAgentNo1());
        failObject.put("agentNo2",  item.getAgentNo2());
        failObject.put("agentNo3",  item.getAgentNo3());
        failObject.put("agentNo4",  item.getAgentNo4());
        failObject.put("ifCode", item.getIfCode());
        failObject.put("ifName", item.getIfName());
        failObject.put("aliSubmerchantNo",  item.getAliSubmerchantNo());
        failObject.put("wechatSubmerchantNo", item.getWechatSubmerchantNo());
        failObject.put("ysfSubmerchantNo", item.getYsfSubmerchantNo());
        failObject.put("phone",  item.getPhone());
        failObject.put("failRemark", failRemark);
        failList.add(failObject);
    }

    /**
     * 导出失败商户数据
     */
    private String importMchFailUrl(List<JSONObject> failList) {
        String failUrl = null;
        if (ObjectUtils.isEmpty(failList)){
            return null;
        }
        //将failSet导出
        String failFileName = String.format("./temp/importMchInfo/fail/%s.xlsx", DateUtil.date().getTime());
        File normalFile = new File(failFileName);
        ExcelWriter failWriter = ExcelUtil.getWriter(normalFile);
        failWriter.addHeaderAlias("mchNo","商户号");
        failWriter.addHeaderAlias("mchName","商户名称");
        failWriter.addHeaderAlias("mchShortName","商户简称");
        failWriter.addHeaderAlias("agentNo","代理商号");
        failWriter.addHeaderAlias("longitude","经度");
        failWriter.addHeaderAlias("latitude","纬度");
        failWriter.addHeaderAlias("address","商户地址");
        failWriter.addHeaderAlias("agentNo1","一级机构号");
        failWriter.addHeaderAlias("agentNo2","二级机构号");
        failWriter.addHeaderAlias("agentNo3","三级机构号");
        failWriter.addHeaderAlias("agentNo4","四级机构号");
        failWriter.addHeaderAlias("ifCode","通道编号");
        failWriter.addHeaderAlias("ifName","通道名称");
        failWriter.addHeaderAlias("aliSubmerchantNo","支付宝间连号");
        failWriter.addHeaderAlias("wechatSubmerchantNo","微信间连号");
        failWriter.addHeaderAlias("ysfSubmerchantNo","云闪付间连号");
        failWriter.addHeaderAlias("phone","手机号");
        failWriter.addHeaderAlias("failRemark","失败原因");
        try {
            failWriter.write(failList);
            failWriter.close();
            MultipartFile multipartFile = new MockMultipartFile(failFileName, normalFile.length(), new FileInputStream(normalFile));
            failUrl = ossFileService.singleFileUpload(multipartFile, OssFileConfig.BIZ_TYPE.DOWNLOAD);
            // 添加oos上传记录
            OssRecordEntity ossRecordEntity = new OssRecordEntity();
            ossRecordEntity.setBizType(OssFileConfig.BIZ_TYPE.DOWNLOAD);
            ossRecordEntity.setOssUrl(failUrl);
            ossRecordEntity.setFileSize(normalFile.length());
            ossRecordEntity.setUploadType(Constants.OSS_UPLOAD_TYPE.MCH_INFO_IMPORT_FAIL);
            ossRecordEntity.setCreatedAt(new Date());
            ossRecordService.save(ossRecordEntity);
            FileUtil.del(normalFile);
        } catch (Exception e) {
            throw new BizException(e.getMessage());
        }
        return failUrl;
    }


    /**
     * oss文件导入
     *
     * @return
     */
    public JSONObject getMchInfoToList(String ossFileUrl, String bizType,String currentAgentNo){
        List<String> oldMchNoList = null;
        List<String> agentNos = null;
        //运营端和机构端判断条件
        if (!"0".equals(currentAgentNo)) {
            //机构下所有
              agentNos = agentInfoService.queryAllSubAgentNo(currentAgentNo);
              //查询本机构和下级机构所有商户
            List<MchInfoEntity> mchInfoEntities = mchInfoMapper.selectList(MchInfoEntity.gw()
                    .select(MchInfoEntity::getMchNo)
                    .in(ObjectUtils.isNotEmpty(agentNos),MchInfoEntity::getAgentNo, agentNos));
            oldMchNoList = mchInfoEntities.stream().map(MchInfoEntity::getMchNo).toList();
        }else {
            //查询数据库中所有商户
            oldMchNoList = mchInfoMapper.getMchNoList();
        }

        //将文件下载到本地
        File file= FileUtil.file(String.format("./temp/%s.xlsx", DateUtil.date().getTime()));
        JSONObject jsonObject = JSONObject.parseObject(ossFileUrl);
        ossFileUrl = jsonObject.getString("ossFileUrl");
        HttpUtil.downloadFile(ossFileUrl, file);

        // 添加oos上传记录
        OssRecordEntity ossRecordEntity = new OssRecordEntity();
        ossRecordEntity.setBizType(bizType);
        ossRecordEntity.setOssUrl(ossFileUrl);
        ossRecordEntity.setFileSize(file.length());
        ossRecordEntity.setUploadType(Constants.OSS_UPLOAD_TYPE.MCH_IMPORT);
        ossRecordEntity.setSysUserId(GzUserDetails.getCurrentUserDetails().getSysUserId());
        ossRecordEntity.setCreatedAt(new Date());
        ossRecordService.save(ossRecordEntity);

        // 读取文件内容
        ExcelReader reader = ExcelUtil.getReader(file);

        reader.addHeaderAlias("商户号","mchNo");
        reader.addHeaderAlias("商户名称","mchName");
        reader.addHeaderAlias("商户简称","mchShortName");
        reader.addHeaderAlias("代理商号","agentNo");
        reader.addHeaderAlias("经度","longitude");
        reader.addHeaderAlias("纬度","latitude");
        reader.addHeaderAlias("商户地址","address");
        reader.addHeaderAlias("一级机构号","agentNo1");
        reader.addHeaderAlias("二级机构号","agentNo2");
        reader.addHeaderAlias("三级机构号","agentNo3");
        reader.addHeaderAlias("四级机构号","agentNo4");
        reader.addHeaderAlias("通道编号","ifCode");
        reader.addHeaderAlias("通道名称","ifName");
        reader.addHeaderAlias("支付宝间连号","aliSubmerchantNo");
        reader.addHeaderAlias("微信间连号","wechatSubmerchantNo");
        reader.addHeaderAlias("云闪付间连号","ysfSubmerchantNo");
        reader.addHeaderAlias("手机号","phone");

        List<MchInfoVO> all = reader.readAll(MchInfoVO.class);
//        List<MchInfoVO> failList = new ArrayList<>();
        List<JSONObject> failList = new ArrayList<>();
        List<MchInfoVO> successList = new ArrayList<>();
        for (int i = 0; i < all.size(); i++) {
            MchInfoVO item = all.get(i);
            Integer total = all.size();
            if (StringUtils.isEmpty(item.getMchNo())){
                toJsonSet(item,  failList,"商户号不能为空");
//                failList.add(item);
//                wsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), total, "导入平台商户数据", "第" + (i + 1) + "行，商户号不能为空", WebSocketConstants.ImportStatus.FAIL);
                continue;
            }
            if (StringUtils.isEmpty(item.getAgentNo())){
                toJsonSet(item,  failList,"代理商号不能为空");
//                failList.add(item);
//                wsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), total, "导入平台商户数据", "第" + (i + 1) + "行，代理商号不能为空", WebSocketConstants.ImportStatus.FAIL);
                continue;
            }
            if (item.getLongitude() == null ||  item.getLatitude() == null){
                toJsonSet(item,  failList,"经纬度不能为空");
//                failList.add(item);
//                wsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), total, "导入平台商户数据", "第" + (i + 1) + "行，经纬度不能为空", WebSocketConstants.ImportStatus.FAIL);
                continue;
            }
            if (StringUtils.isEmpty(item.getMchName()) || StringUtils.isEmpty(item.getMchShortName())){
                toJsonSet(item,  failList,"商户名称和商户简称不能为空");
//                failList.add(item);
//                wsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), total, "导入平台商户数据", "第" + (i + 1) + "行，商户名称和商户简称不能为空", WebSocketConstants.ImportStatus.FAIL);
                continue;
            }
            if (StringUtils.isEmpty(item.getAddress())){
                toJsonSet(item,  failList,"商户地址不能为空");
//                failList.add(item);
//                wsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), total, "导入平台商户数据", "第" + (i + 1) + "行，商户地址不能为空", WebSocketConstants.ImportStatus.FAIL);
                continue;
            }
            //运营端和机构端判断条件
            if (!"0".equals(currentAgentNo)){
                if (ObjectUtils.isNotEmpty(agentNos) && !agentNos.contains(item.getAgentNo())) {
                    toJsonSet(item, failList, "该商户不属于该机构或下级机构");
                    //                    failList.add(item);
//                    wsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), total, "导入平台商户数据", "第" + (i + 1) + "行，该商户不属于该机构或下级机构", WebSocketConstants.ImportStatus.FAIL);
                    continue;
                }
            }
            if (CollUtil.isNotEmpty(oldMchNoList) && oldMchNoList.contains(item.getMchNo())){
                toJsonSet(item, failList, "该商户已存在");
                //                failList.add(item);
//                wsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), total, "导入平台商户数据", "第" + (i + 1) + "行，该商户已存在", WebSocketConstants.ImportStatus.FAIL);
                continue;
            }
            AgentInfoEntity agentInfo = agentInfoService.getAgentInfo(item.getAgentNo());
            if (ObjectUtils.isEmpty(agentInfo)){
                toJsonSet(item, failList, "该代理商号不存在");
                //                failList.add(item);
//                wsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), total, "导入平台商户数据", "第" + (i + 1) + "行，该代理商号不存在", WebSocketConstants.ImportStatus.FAIL);
                continue;
            }
            //手机号正则表达式校验
            if (StringUtils.isNotEmpty(item.getPhone())){
                String phoneRegex="^1[3-9]\\d{9}$";
                if (!item.getPhone().matches(phoneRegex)){
                    toJsonSet(item, failList, "手机号格式不正确");
//                    failList.add(item);
//                    wsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), total, "导入平台商户数据", "第" + (i + 1) + "行，手机号格式不正确", WebSocketConstants.ImportStatus.FAIL);
                    continue;
                }
            }
            item.setAgentNo1(agentInfo.getAgentNo1());
            item.setAgentNo2(agentInfo.getAgentNo2());
            item.setAgentNo3(agentInfo.getAgentNo3());
            item.setAgentNo4(agentInfo.getAgentNo4());

            item.setOssRecordId(ossRecordEntity.getOssRecordId());
            item.setLocation(new PointDTO(new BigDecimal(item.getLongitude().toString()), new BigDecimal(item.getLatitude().toString())));

//            wsChannelServer.convertAndSend(String.valueOf(GzUserDetails.getCurrentUserDetails().getSysUserId()), total, "导入平台商户数据", "第" + (i + 1) + "行，导入成功", WebSocketConstants.ImportStatus.SUCCESS);
            successList.add(item);
        }
        reader.close();
        FileUtil.del(file);
        JSONObject result = new JSONObject();
        result.put("fail",failList);
        result.put("success",successList);
        return result;
    }

    /**
     * 对比商户数据并导出
     */
    public JSONObject compareMchInfo(String ossFileUrl, HttpServletResponse response) {
        if (StringUtils.isEmpty(ossFileUrl)){
            throw new BizException("参数有误，请检查");
        }
        JSONObject resultJson = new JSONObject();
        File file = FileUtil.file(String.format("./temp/%s.xlsx", DateUtil.date().getTime()));
        HttpUtil.downloadFile(ossFileUrl, file);

        // 读取文件内容
        ExcelReader reader = ExcelUtil.getReader(file);
        reader.addHeaderAlias("商户号","mchNo");
        reader.addHeaderAlias("微信间连号","wechatSubmerchantNo");
        reader.addHeaderAlias("支付宝间连号","aliSubmerchantNo");
        List<MchInfoDTO> importMchInfos = reader.readAll(MchInfoDTO.class);
        if (importMchInfos.isEmpty()) {
            throw new BizException("未查询到文件内容");
        }

        // 查询商户信息
        Set<String> importMchNos = importMchInfos.stream().map(MchInfoDTO::getMchNo).collect(Collectors.toSet());
        List<MchInfoEntity> mchInfos = baseMapper.selectList(MchInfoEntity.gw().in(MchInfoEntity::getMchNo, importMchNos).select(MchInfoEntity::getMchNo));
        List<String> mchNos = mchInfos.stream().map(MchInfoEntity::getMchNo).collect(Collectors.toList());

        // 商户间连号map
        Map<String, MchChannelEntity> mchChannelMap = new HashMap<>();
        if (!mchNos.isEmpty()) {
            // 查询间连号
            LambdaQueryWrapper<MchChannelEntity> gw = MchChannelEntity.gw().in(MchChannelEntity::getMchNo, mchNos).eq(MchChannelEntity::getState, 1)
                    .select(MchChannelEntity::getMchNo, MchChannelEntity::getWechatSubmerchantNo, MchChannelEntity::getAliSubmerchantNo);
            List<MchChannelEntity> mchChannelList = mchChannelService.list(gw);
            mchChannelMap = mchChannelList.stream().collect(Collectors.toMap(MchChannelEntity::getMchNo, Function.identity(), (a, b) -> b));
        }

        // 正常商户集合
        List<JSONObject> successJson = new ArrayList<>();
        // 异常商户集合
        List<JSONObject> failJson = new ArrayList<>();
        // 对比数据
        for (MchInfoDTO importMchInfo : importMchInfos) {
            JSONObject jsonResult = new JSONObject();

            jsonResult.put("mchNo",importMchInfo.getMchNo());
            jsonResult.put("wechatSubmerchantNo",importMchInfo.getWechatSubmerchantNo());
            jsonResult.put("aliSubmerchantNo",importMchInfo.getAliSubmerchantNo());
            if (!mchNos.contains(importMchInfo.getMchNo())) {
                jsonResult.put("remark","该商户不存在");
                failJson.add(jsonResult);
                continue;
            }
            if (!mchChannelMap.containsKey(importMchInfo.getMchNo())) {
                jsonResult.put("remark","未查询到进件信息");
                failJson.add(jsonResult);
                continue;
            }
            // 对比间连号
            StringBuilder remark = new StringBuilder();
            MchChannelEntity mchChannelEntity = mchChannelMap.get(importMchInfo.getMchNo());
            // 微信间连号
            if (ObjectUtils.isEmpty(importMchInfo.getWechatSubmerchantNo())) {
                if (ObjectUtils.isNotEmpty(mchChannelEntity.getWechatSubmerchantNo())) {
                    remark.append("微信间连号不匹配，正确微信间连号：").append(mchChannelEntity.getWechatSubmerchantNo()).append(";");
                }
            }else {
                if (!importMchInfo.getWechatSubmerchantNo().equals(mchChannelEntity.getWechatSubmerchantNo())) {
                    remark.append("微信间连号不匹配，正确微信间连号：").append(mchChannelEntity.getWechatSubmerchantNo()).append(";");
                }
            }
            // 支付宝间连号
            if (ObjectUtils.isEmpty(importMchInfo.getAliSubmerchantNo())) {
                if (ObjectUtils.isNotEmpty(mchChannelEntity.getAliSubmerchantNo())) {
                    remark.append("支付宝间连号不匹配，正确支付宝间连号：").append(mchChannelEntity.getAliSubmerchantNo()).append(";");
                }
            }else {
                if (!importMchInfo.getAliSubmerchantNo().equals(mchChannelEntity.getAliSubmerchantNo())) {
                    remark.append("支付宝间连号不匹配，正确支付宝间连号：").append(mchChannelEntity.getAliSubmerchantNo()).append(";");
                }
            }
            if (!remark.isEmpty()) {
                jsonResult.put("remark",remark.toString());
                failJson.add(jsonResult);
                continue;
            }
            successJson.add(jsonResult);
        }
        resultJson.put("successUrl",successOssUrl(successJson));
        resultJson.put("failUrl",failOssUrl(failJson));
        return resultJson;
    }

    /**
     * 对比商户数据成功的结果文件
     * @param jsonObjects
     * @return
     */
    public String successOssUrl(List<JSONObject> jsonObjects){
        String successUrl = "";
        if (!jsonObjects.isEmpty()) {
            String successFileName = String.format("./temp/compareMchInfo/success/%s.xlsx", DateUtil.date().getTime());
            File normalFile = new File(successFileName);
            ExcelWriter successWriter = ExcelUtil.getWriter(normalFile);
            successWriter.renameSheet("正常商户数据");
            successWriter.addHeaderAlias("mchNo", "商户号");
            successWriter.addHeaderAlias("wechatSubmerchantNo", "微信间连号");
            successWriter.addHeaderAlias("aliSubmerchantNo", "支付宝间连号");
            try {
                successWriter.write(jsonObjects);
                successWriter.close();
                MultipartFile multipartFile = new MockMultipartFile(successFileName, normalFile.length(), new FileInputStream(normalFile));
                successUrl = ossFileService.singleFileUpload(multipartFile, OssFileConfig.BIZ_TYPE.DOWNLOAD);
                // 添加oos上传记录
                OssRecordEntity ossRecordEntity = new OssRecordEntity();
                ossRecordEntity.setBizType("yx");
                ossRecordEntity.setOssUrl(successUrl);
                ossRecordEntity.setFileSize(normalFile.length());
                ossRecordEntity.setUploadType(Constants.OSS_UPLOAD_TYPE.MCH_INFO_COMPARE_SUCCESS);
                ossRecordEntity.setCreatedAt(new Date());
                ossRecordService.save(ossRecordEntity);
            } catch (Exception e) {
                throw new BizException(e.getMessage());
            }
        }
        return successUrl;
    }

    /**
     * 对比商户数据失败的结果文件
     * @param jsonObjects
     * @return
     */
    public String failOssUrl(List<JSONObject> jsonObjects){
        String failUrl = "";
        if (!jsonObjects.isEmpty()) {
            String successFileName = String.format("./temp/compareMchInfo/fail/%s.xlsx", DateUtil.date().getTime());
            File normalFile = new File(successFileName);
            ExcelWriter failWriter = ExcelUtil.getWriter(normalFile);
            failWriter.addHeaderAlias("mchNo", "商户号");
            failWriter.addHeaderAlias("wechatSubmerchantNo", "微信间连号");
            failWriter.addHeaderAlias("aliSubmerchantNo", "支付宝间连号");
            failWriter.addHeaderAlias("remark", "对比结果");
            try {
                failWriter.write(jsonObjects);
                failWriter.close();
                MultipartFile multipartFile = new MockMultipartFile(successFileName, normalFile.length(), new FileInputStream(normalFile));
                failUrl = ossFileService.singleFileUpload(multipartFile, OssFileConfig.BIZ_TYPE.DOWNLOAD);
                // 添加oos上传记录
                OssRecordEntity ossRecordEntity = new OssRecordEntity();
                ossRecordEntity.setBizType("yx");
                ossRecordEntity.setOssUrl(failUrl);
                ossRecordEntity.setFileSize(normalFile.length());
                ossRecordEntity.setUploadType(Constants.OSS_UPLOAD_TYPE.MCH_INFO_COMPARE_FAIL);
                ossRecordEntity.setCreatedAt(new Date());
                ossRecordService.save(ossRecordEntity);
            } catch (Exception e) {
                throw new BizException(e.getMessage());
            }
        }
        return failUrl;
    }

    /**获取用户的周围的商户列表**/
    public IPage<NearMchListVo> getNearMchList(IPage<?> iPage, PointDTO location, String radius, Long couponId) {
        if(ObjectUtils.isEmpty(location) || Objects.isNull(couponId)){
           throw new BizException("请求参数缺失！");
        }
        IPage<NearMchListVo> page = mchInfoMapper.getNearMchList(iPage, location, radius, couponId);
        Stream<NearMchListVo> sorted = page.getRecords().stream().sorted(Comparator.comparing(NearMchListVo::getOrderSort, Comparator.reverseOrder()));
        List<NearMchListVo> collect = sorted.collect(Collectors.toList());
        page.setRecords(collect);
        return page;
    }

    /**
     * 修改商户图片
     * @param mchNo
     * @param imageUrl
     */
    public void updateMchImage(String mchNo, String imageUrl) {
        if (StringUtils.isEmpty(mchNo) || StringUtils.isEmpty(imageUrl)) {
            throw new BizException("参数有误，请检查");
        }
        MchInfoEntity mchInfo = getById(mchNo);
        if(ObjectUtils.isEmpty(mchInfo)){
            throw new BizException("该商户不存在，请检查");
        }
        MchInfoEntity entity = new MchInfoEntity();
        entity.setMchNo(mchNo);
        entity.setMchListImage(imageUrl);
        updateById(entity);
    }

    /**
     * 修改商户详情图片
     * @param mchNo
     * @param mchBannerImage
     */
    public void updateBannerImage(String mchNo, String mchBannerImage) {
        if (StringUtils.isEmpty(mchNo) || StringUtils.isEmpty(mchBannerImage)) {
            throw new BizException("参数有误，请检查");
        }
        MchInfoEntity mchInfo = getById(mchNo);
        if(ObjectUtils.isEmpty(mchInfo)){
            throw new BizException("该商户不存在，请检查");
        }
        MchInfoEntity entity = new MchInfoEntity();
        entity.setMchNo(mchNo);
        entity.setMchBannerImage(mchBannerImage);
        updateById(entity);
    }

    /**
     * 精选商户置顶
     * @param mchNo
     * @param order
     */
    public void updateMchOrderSort(String mchNo, Integer order) {
        if (StringUtils.isEmpty(mchNo)) {
           throw new BizException("参数有误，请检查");
        }
        MchInfoEntity mchInfo = getById(mchNo);
        if (ObjectUtils.isEmpty(mchInfo)) {
            throw new BizException("该商户不存在，请检查");
        }
        MchInfoEntity entity = new MchInfoEntity();
        entity.setMchNo(mchNo);
        entity.setOrderSort(order == null || order < 0 ? 0 : order);
        updateById(entity);
    }

    public MchInfoEntity mchInfo(String mchNo) {
        return mchInfoMapper.mchInfo(mchNo);
    }

    /**
     * 添加商户信息
     * @param mchInfo
     */
    public int addMchInfo(MchInfoEntity mchInfo) {
        return mchInfoMapper.addMchInfo(mchInfo);
    }

    /**
     * 修改商户信息
     * @param mchInfo
     * @return
     */
    public int updateMchInfoById(MchInfoEntity mchInfo) {
        return mchInfoMapper.updateMchInfoById(mchInfo);
    }
}
